package controllers

import (
	"blog-backend/internal/app/dtos"
	"blog-backend/internal/app/services"
	"blog-backend/internal/utils"
	"net/http"
	"strconv"

	"github.com/gin-gonic/gin"
)

type PostController struct {
	postService *services.PostService
}

func NewPostController() *PostController {
	return &PostController{
		postService: services.NewPostService(),
	}
}

// GetPosts 获取文章列表
// @Summary 获取文章列表
// @Description 获取已发布的文章列表（分页）
// @Tags 文章
// @Produce json
// @Param page query int false "页码" default(1)
// @Param limit query int false "每页数量" default(10)
// @Success 200 {object} dtos.SuccessResponse{data=dtos.PostListResult} "获取成功"
// @Failure 500 {object} dtos.ErrorResponse "服务器内部错误"
// @Router /api/posts [get]
func (c *PostController) GetPosts(ctx *gin.Context) {
	page, _ := strconv.Atoi(ctx.DefaultQuery("page", "1"))
	limit, _ := strconv.Atoi(ctx.DefaultQuery("limit", "10"))

	posts, total, err := c.postService.GetPosts(page, limit)
	if err != nil {
		utils.RespondError(ctx, http.StatusInternalServerError, err.Error())
		return
	}

	// 构建响应DTO
	var postList []dtos.PostListResponse
	for _, post := range posts {
		postList = append(postList, dtos.PostListResponse{
			ID:         post.ID,
			Title:      post.Title,
			Slug:       post.Slug,
			Excerpt:    post.Excerpt,
			CoverImage: post.CoverImage,
			User: dtos.UserInfo{
				ID:       post.User.ID,
				Username: post.User.Username,
				Avatar:   post.User.Avatar,
			},
			Category: dtos.CategoryInfo{
				ID:   post.Category.ID,
				Name: post.Category.Name,
				Slug: post.Category.Slug,
			},
			Tags: func() []dtos.TagInfo {
				var tags []dtos.TagInfo
				for _, tag := range post.Tags {
					tags = append(tags, dtos.TagInfo{
						ID:   tag.ID,
						Name: tag.Name,
						Slug: tag.Slug,
					})
				}
				return tags
			}(),
			ViewCount: post.ViewCount,
			CreatedAt: post.CreatedAt,
		})
	}

	totalPages := (total + int64(limit) - 1) / int64(limit)
	if totalPages == 0 {
		totalPages = 1
	}

	utils.RespondJSON(ctx, http.StatusOK, dtos.SuccessResponse{
		Success: true,
		Message: "获取文章列表成功",
		Data: dtos.PostListResult{
			Posts:     postList,
			Total:     total,
			Page:      page,
			TotalPage: int(totalPages),
		},
	})
}

// GetPost 获取文章详情
// @Summary 获取文章详情
// @Description 根据ID获取文章详情
// @Tags 文章
// @Produce json
// @Param id path int true "文章ID"
// @Success 200 {object} dtos.SuccessResponse{data=dtos.PostResponse} "获取成功"
// @Failure 400 {object} dtos.ErrorResponse "无效的文章ID"
// @Failure 404 {object} dtos.ErrorResponse "文章不存在"
// @Failure 500 {object} dtos.ErrorResponse "服务器内部错误"
// @Router /api/posts/{id} [get]
func (c *PostController) GetPost(ctx *gin.Context) {
	id := ctx.Param("id")
	postID, err := strconv.ParseUint(id, 10, 32)
	if err != nil {
		utils.RespondError(ctx, http.StatusBadRequest, "无效的文章ID")
		return
	}

	post, err := c.postService.GetPost(uint(postID))
	if err != nil {
		utils.RespondError(ctx, http.StatusNotFound, "文章不存在")
		return
	}

	// 构建响应DTO
	response := dtos.PostResponse{
		ID:          post.ID,
		Title:       post.Title,
		Slug:        post.Slug,
		Excerpt:     post.Excerpt,
		Content:     post.Content,
		CoverImage:  post.CoverImage,
		Status:      post.Status,
		ViewCount:   post.ViewCount,
		PublishedAt: post.PublishedAt,
		CreatedAt:   post.CreatedAt,
		UpdatedAt:   post.UpdatedAt,
		User: dtos.UserInfo{
			ID:       post.User.ID,
			Username: post.User.Username,
			Avatar:   post.User.Avatar,
		},
		Category: dtos.CategoryInfo{
			ID:   post.Category.ID,
			Name: post.Category.Name,
			Slug: post.Category.Slug,
		},
	}

	// 添加标签信息
	for _, tag := range post.Tags {
		response.Tags = append(response.Tags, dtos.TagInfo{
			ID:   tag.ID,
			Name: tag.Name,
			Slug: tag.Slug,
		})
	}

	utils.RespondJSON(ctx, http.StatusOK, dtos.SuccessResponse{
		Success: true,
		Message: "获取文章详情成功",
		Data:    response,
	})
}

// CreatePost 创建文章
// @Summary 创建文章
// @Description 创建新文章
// @Tags 文章
// @Accept json
// @Produce json
// @Security Bearer
// @Param post body dtos.CreatePostDto true "文章内容"
// @Success 201 {object} dtos.SuccessResponse{data=dtos.PostResponse} "创建成功"
// @Failure 400 {object} dtos.ErrorResponse "请求参数错误"
// @Failure 401 {object} dtos.ErrorResponse "未认证"
// @Failure 409 {object} dtos.ErrorResponse "URL标识已被使用"
// @Failure 500 {object} dtos.ErrorResponse "服务器内部错误"
// @Router /api/posts [post]
func (c *PostController) CreatePost(ctx *gin.Context) {
	userID := ctx.MustGet("userID").(uint)

	var dto dtos.CreatePostDto
	if err := ctx.ShouldBindJSON(&dto); err != nil {
		utils.RespondError(ctx, http.StatusBadRequest, err.Error())
		return
	}

	post, err := c.postService.CreatePost(dto, userID)
	if err != nil {
		utils.RespondError(ctx, http.StatusConflict, err.Error())
		return
	}

	// 构建响应DTO
	response := dtos.PostResponse{
		ID:          post.ID,
		Title:       post.Title,
		Slug:        post.Slug,
		Excerpt:     post.Excerpt,
		Content:     post.Content,
		CoverImage:  post.CoverImage,
		Status:      post.Status,
		ViewCount:   post.ViewCount,
		PublishedAt: post.PublishedAt,
		CreatedAt:   post.CreatedAt,
		UpdatedAt:   post.UpdatedAt,
		User: dtos.UserInfo{
			ID:       post.User.ID,
			Username: post.User.Username,
			Avatar:   post.User.Avatar,
		},
		Category: dtos.CategoryInfo{
			ID:   post.Category.ID,
			Name: post.Category.Name,
			Slug: post.Category.Slug,
		},
	}

	utils.RespondJSON(ctx, http.StatusCreated, dtos.SuccessResponse{
		Success: true,
		Message: "创建文章成功",
		Data:    response,
	})
}

// UpdatePost 更新文章
// @Summary 更新文章
// @Description 更新现有文章
// @Tags 文章
// @Accept json
// @Produce json
// @Security Bearer
// @Param id path int true "文章ID"
// @Param post body dtos.UpdatePostDto true "更新内容"
// @Success 200 {object} dtos.SuccessResponse{data=dtos.PostResponse} "更新成功"
// @Failure 400 {object} dtos.ErrorResponse "请求参数错误"
// @Failure 401 {object} dtos.ErrorResponse "未认证"
// @Failure 403 {object} dtos.ErrorResponse "无权修改此文章"
// @Failure 404 {object} dtos.ErrorResponse "文章不存在"
// @Failure 409 {object} dtos.ErrorResponse "URL标识已被使用"
// @Failure 500 {object} dtos.ErrorResponse "服务器内部错误"
// @Router /api/posts/{id} [put]
func (c *PostController) UpdatePost(ctx *gin.Context) {
	id := ctx.Param("id")
	postID, err := strconv.ParseUint(id, 10, 32)
	if err != nil {
		utils.RespondError(ctx, http.StatusBadRequest, "无效的文章ID")
		return
	}

	userID := ctx.MustGet("userID").(uint)

	var dto dtos.UpdatePostDto
	if err := ctx.ShouldBindJSON(&dto); err != nil {
		utils.RespondError(ctx, http.StatusBadRequest, err.Error())
		return
	}

	post, err := c.postService.UpdatePost(uint(postID), dto, userID)
	if err != nil {
		status := http.StatusInternalServerError
		if err.Error() == "无权修改此文章" {
			status = http.StatusForbidden
		} else if err.Error() == "URL标识已被使用" {
			status = http.StatusConflict
		} else if err.Error() == "文章不存在" {
			status = http.StatusNotFound
		}
		utils.RespondError(ctx, status, err.Error())
		return
	}

	// 构建响应DTO
	response := dtos.PostResponse{
		ID:          post.ID,
		Title:       post.Title,
		Slug:        post.Slug,
		Excerpt:     post.Excerpt,
		Content:     post.Content,
		CoverImage:  post.CoverImage,
		Status:      post.Status,
		ViewCount:   post.ViewCount,
		PublishedAt: post.PublishedAt,
		CreatedAt:   post.CreatedAt,
		UpdatedAt:   post.UpdatedAt,
		User: dtos.UserInfo{
			ID:       post.User.ID,
			Username: post.User.Username,
			Avatar:   post.User.Avatar,
		},
		Category: dtos.CategoryInfo{
			ID:   post.Category.ID,
			Name: post.Category.Name,
			Slug: post.Category.Slug,
		},
	}

	utils.RespondJSON(ctx, http.StatusOK, dtos.SuccessResponse{
		Success: true,
		Message: "更新文章成功",
		Data:    response,
	})
}

// DeletePost 删除文章
// @Summary 删除文章
// @Description 删除现有文章
// @Tags 文章
// @Produce json
// @Security Bearer
// @Param id path int true "文章ID"
// @Success 200 {object} dtos.SuccessResponse "删除成功"
// @Failure 400 {object} dtos.ErrorResponse "无效的文章ID"
// @Failure 401 {object} dtos.ErrorResponse "未认证"
// @Failure 403 {object} dtos.ErrorResponse "无权删除此文章"
// @Failure 404 {object} dtos.ErrorResponse "文章不存在"
// @Failure 500 {object} dtos.ErrorResponse "服务器内部错误"
// @Router /api/posts/{id} [delete]
func (c *PostController) DeletePost(ctx *gin.Context) {
	id := ctx.Param("id")
	postID, err := strconv.ParseUint(id, 10, 32)
	if err != nil {
		utils.RespondError(ctx, http.StatusBadRequest, "无效的文章ID")
		return
	}

	userID := ctx.MustGet("userID").(uint)

	if err := c.postService.DeletePost(uint(postID), userID); err != nil {
		status := http.StatusInternalServerError
		if err.Error() == "无权删除此文章" {
			status = http.StatusForbidden
		} else if err.Error() == "文章不存在" {
			status = http.StatusNotFound
		}
		utils.RespondError(ctx, status, err.Error())
		return
	}

	utils.RespondJSON(ctx, http.StatusOK, dtos.SuccessResponse{
		Success: true,
		Message: "删除文章成功",
	})
}

// GetPostBySlug 通过Slug获取文章
// @Summary 通过Slug获取文章
// @Description 根据URL标识获取文章详情
// @Tags 文章
// @Produce json
// @Param slug path string true "文章Slug"
// @Success 200 {object} dtos.SuccessResponse{data=dtos.PostResponse} "获取成功"
// @Failure 404 {object} dtos.ErrorResponse "文章不存在"
// @Failure 500 {object} dtos.ErrorResponse "服务器内部错误"
// @Router /api/posts/slug/{slug} [get]
func (c *PostController) GetPostBySlug(ctx *gin.Context) {
	slug := ctx.Param("slug")

	post, err := c.postService.GetPostBySlug(slug)
	if err != nil {
		utils.RespondError(ctx, http.StatusNotFound, "文章不存在")
		return
	}

	// 构建响应DTO
	response := dtos.PostResponse{
		ID:          post.ID,
		Title:       post.Title,
		Slug:        post.Slug,
		Excerpt:     post.Excerpt,
		Content:     post.Content,
		CoverImage:  post.CoverImage,
		Status:      post.Status,
		ViewCount:   post.ViewCount,
		PublishedAt: post.PublishedAt,
		CreatedAt:   post.CreatedAt,
		UpdatedAt:   post.UpdatedAt,
		User: dtos.UserInfo{
			ID:       post.User.ID,
			Username: post.User.Username,
			Avatar:   post.User.Avatar,
		},
		Category: dtos.CategoryInfo{
			ID:   post.Category.ID,
			Name: post.Category.Name,
			Slug: post.Category.Slug,
		},
	}

	// 添加标签信息
	for _, tag := range post.Tags {
		response.Tags = append(response.Tags, dtos.TagInfo{
			ID:   tag.ID,
			Name: tag.Name,
			Slug: tag.Slug,
		})
	}

	utils.RespondJSON(ctx, http.StatusOK, dtos.SuccessResponse{
		Success: true,
		Message: "获取文章详情成功",
		Data:    response,
	})
}